package edu.ynu.se.xiecheng.achitectureclass.soildata.service;

import edu.ynu.se.xiecheng.achitectureclass.device.entity.Device;
import edu.ynu.se.xiecheng.achitectureclass.device.service.DeviceService;
import edu.ynu.se.xiecheng.achitectureclass.device.enums.DeviceCategory;
import edu.ynu.se.xiecheng.achitectureclass.soildata.dao.*;
import edu.ynu.se.xiecheng.achitectureclass.soildata.entity.BaseSensorData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.sql.Timestamp;
import java.util.Date;

@Service
public class SensorDataService {

    private static final Logger logger = LoggerFactory.getLogger(SensorDataService.class);

    @Autowired
    private DeviceService deviceService;
    
    @Autowired
    private SoilMoistureDataDAO soilMoistureDataDAO;
    
    @Autowired
    private SoilTemperatureDataDAO soilTemperatureDataDAO;
    
    @Autowired
    private SoilConductivityDataDAO soilConductivityDataDAO;
    
    @Autowired
    private SoilPHDataDAO soilPHDataDAO;
    
    @Autowired
    private SoilNitrogenDataDAO soilNitrogenDataDAO;
    
    @Autowired
    private SoilPhosphorusDataDAO soilPhosphorusDataDAO;
    
    @Autowired
    private SoilPotassiumDataDAO soilPotassiumDataDAO;
    
    @Autowired
    private AirTemperatureDataDAO airTemperatureDataDAO;
    
    @Autowired
    private AirHumidityDataDAO airHumidityDataDAO;
    
    @Autowired
    private CO2DataDAO co2DataDAO;
    
    @Autowired
    private LightIntensityDataDAO lightIntensityDataDAO;
    
    // ... 其他DAO注入
    
    public Map<String, Object> getSensorData(Device device, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 转换 LocalDateTime 为 Date
            Date startDate = Timestamp.valueOf(startTime);
            Date endDate = Timestamp.valueOf(endTime);
            
            DeviceCategory category = DeviceCategory.fromString(device.getCategory());
            switch (category) {
                case SOIL_MOISTURE:
                    result.put("data", soilMoistureDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_TEMPERATURE:
                    result.put("data", soilTemperatureDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_CONDUCTIVITY:
                    result.put("data", soilConductivityDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_PH:
                    result.put("data", soilPHDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_NITROGEN:
                    result.put("data", soilNitrogenDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_PHOSPHORUS:
                    result.put("data", soilPhosphorusDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_POTASSIUM:
                    result.put("data", soilPotassiumDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case SOIL_CO2:
                    result.put("data", co2DataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case AIR_TEMPERATURE:
                    result.put("data", airTemperatureDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case AIR_HUMIDITY:
                case RELATIVE_HUMIDITY:
                    result.put("data", airHumidityDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case LIGHT_INTENSITY:
                    result.put("data", lightIntensityDataDAO.findByDeviceAndCreateTimeBetweenOrderByCreateTimeAsc(
                        device, startDate, endDate));
                    break;
                case CAMERA:
                    throw new IllegalArgumentException("摄像头设备不支持数据查询");
                default:
                    throw new IllegalArgumentException("未知的设备类型: " + category);
            }
            
            result.put("success", true);
            result.put("message", "获取数据成功");
        } catch (IllegalArgumentException e) {
            result.put("success", false);
            result.put("message", "设备类型错误: " + e.getMessage());
            logger.error("设备类型错误: {}", device.getCategory(), e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取数据失败: " + e.getMessage());
            logger.error("获取数据失败", e);
        }
        
        return result;
    }
    
    public Map<String, Object> getLatestData(String greenhouseNumber) {
        // 获取大棚下所有设备
        List<Device> devices = deviceService.getSoilDevices(greenhouseNumber);
        Map<String, Object> result = new HashMap<>();
        
        for (Device device : devices) {
            Map<String, Object> deviceData = new HashMap<>();
            deviceData.put("device", device);
            
            // 根据设备类型获取对应的DAO
            SensorDataDAO<?> dao = getSensorDataDAO(device.getCategory());
            if (dao != null) {
                try {
                    Object latestData = dao.findFirstByDeviceOrderByCreateTimeDesc(device);
                    deviceData.put("latestData", latestData);
                    // 添加日志，帮助排查问题
                    if (latestData == null) {
                        logger.warn("设备 {} ({}) 没有找到最新数据", device.getDeviceNumber(), device.getName());
                    }
                } catch (Exception e) {
                    logger.error("获取设备 {} 最新数据失败: {}", device.getDeviceNumber(), e.getMessage());
                    deviceData.put("latestData", null);
                }
            } else {
                logger.warn("设备 {} 类型 {} 没有对应的DAO", device.getDeviceNumber(), device.getCategory());
                deviceData.put("latestData", null);
            }
            
            result.put(device.getDeviceNumber(), deviceData);
        }
        
        return result;
    }

    private SensorDataDAO<?> getSensorDataDAO(String category) {
        try {
            DeviceCategory deviceCategory = DeviceCategory.fromString(category);
            switch (deviceCategory) {
                case SOIL_MOISTURE: return soilMoistureDataDAO;
                case SOIL_TEMPERATURE: return soilTemperatureDataDAO;
                case SOIL_CONDUCTIVITY: return soilConductivityDataDAO;
                case SOIL_PH: return soilPHDataDAO;
                case SOIL_NITROGEN: return soilNitrogenDataDAO;
                case SOIL_PHOSPHORUS: return soilPhosphorusDataDAO;
                case SOIL_POTASSIUM: return soilPotassiumDataDAO;
                case SOIL_CO2: return co2DataDAO;
                case AIR_TEMPERATURE: return airTemperatureDataDAO;
                case AIR_HUMIDITY: return airHumidityDataDAO;
                case RELATIVE_HUMIDITY: return airHumidityDataDAO;
                case LIGHT_INTENSITY: return lightIntensityDataDAO;
                case CAMERA: return null;
                default:
                    logger.warn("未知的设备类型: {}", category);
                    return null;
            }
        } catch (IllegalArgumentException e) {
            logger.warn("无效的设备类型: {}", category);
            return null;
        }
    }
} 